除了前面一在提到的 Lazy Load 和 Infinity Scroll 外,還有其他好玩的應用,簡單跟大家分享幾個我常在用的
我們可以用 Intersection Observer 來觀察使用者是否看了頁面中的某些重要內容,例如促銷訊息、新功能、教學 ... 等,但如果只是單純記錄,其實用 Google Analytics 的事件也比較方便,所以我通常是用來判斷當使用者看了某些內容後,我們要觸發特定的事件,讓使用者有耳目一新的感覺。
功能實作起來不難,唯一要注意的是,當使用者看過這個內容後,就可以停止觀察該元素,避免重複觸發,讓使用者覺得很煩 XXD。所以這中間的互動要掌握得好,既要讓使用者覺得貼心,又不要覺得一直備受打擾。
const specialContent = document.getElementById('special-content');
const logUserEngagement = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('使用者正在查看特定內容');
      // 停止觀察,避免重複觸發
      observer.unobserve(entry.target);
    }
  });
};
const observer = new IntersectionObserver(logUserEngagement, { threshold: 1.0 });
observer.observe(specialContent);
在做展示型的網站時,可能會希望切到不同的區域時,可以將選單的背景色修改成對應的樣式,以往習慣監聽 scroll 滾動事件,再根據高度計算區域範圍,再給選單設定對應的 CSS。現在也可以試著用 IntersectionObserver 取代監聽滾動:
<style>
  body, html {
    margin: 0;
    padding: 0;
  }
  header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    transition: background-color 0.3s ease;
  }
  nav {
    display: flex;
    justify-content: center;
    padding: 1rem;
  }
  nav a {
    color: white;
    text-decoration: none;
    margin: 0 1rem;
  }
  section {
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    font-weight: bold;
  }
  #section1 { background-color: #FFCCCB; }
  #section2 { background-color: #CCCCFF; }
  #section3 { background-color: #D3EFD3; }
</style>
<header id="mainHeader">
    <nav>
      <a href="#section1">Section 1</a>
      <a href="#section2">Section 2</a>
      <a href="#section3">Section 3</a>
    </nav>
</header>
<section id="section1" data-color="#FF6666">
  <h2>Section 1</h2>
</section>
<section id="section2" data-color="#6666FF">
  <h2>Section 2</h2>
</section>
<section id="section3" data-color="#94A437">
  <h2>Section 3</h2>
</section>
const header = document.getElementById('mainHeader');
const sections = document.querySelectorAll('section');
const observerOptions = {
  threshold: 0.5
};
const observerCallback = (entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      header.style.backgroundColor = entry.target.dataset.color;
    }
  });
};
const observer = new IntersectionObserver(observerCallback, observerOptions);
sections.forEach(section => {
  observer.observe(section);
});
在某些情況下,我們不希望頁面一載入就執行所有 JavaScript,而是希望根據需要延遲載入,此時也能利用 IntersectionObserver 這小技巧來優化頁面,讓使用者滑動到特定元素時才執行與這些元素相關的程式碼。
const scriptsToLoad = document.querySelectorAll('.lazy-script');
const loadScript = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const script = document.createElement('script');
      script.src = entry.target.dataset.src;
      script.onload = () => {
        const sectionId = entry.target.closest('section').id;
        const outputId = 'output' + sectionId.slice(-1);
        document.getElementById(outputId).textContent = `${sectionId} 已加載並執行`;
      };
      document.body.appendChild(script);
      observer.unobserve(entry.target);
    }
  });
};
const observer = new IntersectionObserver(loadScript, { threshold: 0.5 });
scriptsToLoad.forEach(script => observer.observe(script));
https://mukiwu.github.io/web-api-demo/observer2.html
以上,有任何問題,都歡迎留言討論